package game;

import java.awt.Point;
import java.util.HashSet;
import java.util.Set;

/**
 * Implements the 8 Queen's Problem. The player is given eight queens and must place all eight queens on the board without 
 * threatening any other <tt>Queen</tt> already placed on the board.
 * 
 * @author Nicole Waldrum
 * @date January 30. 2010
 * @version 1.0
 * 
 * @author Mark Kelly
 * @date February 20, 2010
 * @version 2.0
 *
 */
public class EightQueens extends GameType {
	private static final int QUEENS_FOR_WIN = 8;
	
	// Instance Variables
	private Set<Queen> queens;
	/**
	 * Creates a new instance of EightQueens.
	 * 
	 * After this constructor returns, setGameState() must be called before any other method is invoked.
	 */
	public EightQueens() {
		super();
		queens = new HashSet<Queen>();
	}
	
	/**
	 * {@inheritDoc}
	 * 
	 * In the case of the Eight Queens Problem, it must be noted that another <tt>Queen</tt> is on the board.
	 */
	public void pieceMoved (Piece p) {
		if (p instanceof Queen)
			queens.add((Queen)p);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * In the case of the Eight Queens Problem, an empty board is created.
	 */
	@Override
	public void setupBoard() {
		state.setBoard(new ChessBoard(boardSize));
	}

	/**
	 * {@inheritDoc}
	 * 
	 * In the case of the Eight Queens Problem, eight queens must be on the board and not in each other's movement paths.
	 */
	@Override
	public boolean hasWon(Team team) {
		return (queens.size() == EightQueens.QUEENS_FOR_WIN);
	}
	
	/**
	 * {@inheritDoc}
	 * 
	 * In the case of the Eight Queens Problem, a <tt>Queen</tt> cannot be placed in the movement path of another <tt>Queen</tt>.
	 */
	public boolean isValidMove(Piece piece, Point dest) {
		if (state.getBoard().hasPieceAt(dest))
			return false;
		
		// Can another Queen reach this location?
		for (Piece p : state.getBoard().getAllPieces()) {
			if (p.isValidMove(p, dest)) {
				return false;
			}
		}
		return true;
	}
	
	public boolean movePiece(Point start, Point dest) {
		ChessBoard board = state.getBoard();
		Piece queen = new Queen(dest, Team.WHITE);
		if (isValidMove(queen, dest)) {
			board.movePiece(queen, dest);
			state.pieceMoved(queen);
			return true;
		}
		return false;
	}
}
